package loveqq.hello;

import reactor.core.publisher.Flux;
import reactor.core.publisher.Mono;

import java.util.Comparator;

public class HelloWorld {
    public static void main(String[] args) {
        hello();
        // generate();
        // mapVsFlatMap();
        // zip();
    }

    private static void hello() {
        // 单元素管道(一次只传输0或1个元素)，顺序：doOnSubscribe -> doOnSuccess -> doOnNext
        Mono.just("Hello")  // Mono<String>
                .doOnSubscribe(s -> System.out.printf("Mono doOnSubscribe: [%s]\n", s))
                .doOnSuccess(v -> System.out.printf("Mono doOnSuccess: [%s]\n", v))
                .doOnNext(v -> System.out.printf("Mono doOnNext: [%s]\n", v))
                .block();   // 阻塞式打开管道，处理完一个才继续处理下一个
        // 也有 subscribe()

        System.out.println("--------------------");

        Flux.just(1, 2, 3, 4, 5, 6) // Flux<Integer>
                .sort(Comparator.reverseOrder())    // 倒序
                .doOnSubscribe(s -> System.out.printf("Flux doOnSubscribe: [%s]\n", s))
                .doOnNext(v -> System.out.printf("Flux doOnNext: [%s]\n", v))
                .doOnComplete(() -> System.out.println("Flux doOnComplete: []"))
                .subscribe();   // 非阻塞式打开管道
    }

    private static void generate() {
        // 初始化1，步长2，生成特定字符串
        Flux.generate(() -> 1, (value, sink) -> {
            if (value >= 20) {
                sink.complete();
            }
            sink.next("value-" + value);
            return value + 2;
        }).doOnNext(System.out::println)
                .subscribe();
    }

    private static void mapVsFlatMap() {
        System.out.println("--------------map-------------------");
        Flux.just(1, 2, 3, 4, 5, 6)
                .map(i -> {
                    if (i > 4) {
                        throw new RuntimeException("map: i == 4");
                    }
                    return "num-" + i;
                })
                .doOnNext(System.out::println)
                .subscribe();

        System.out.println("--------------flatMap-------------------");

        Flux.just(1, 2, 3, 4, 5, 6)
                .flatMap(i -> (i > 4) ? Mono.error(new RuntimeException("flatMap: i==4")) : Mono.just("num-" + i))
                .doOnNext(System.out::println)
                .subscribe();
    }

    private static void zip() {
        // zip()最多支持6个，生成元组
        Flux.zip(
                Flux.just(1, 2, 3),   // ID
                Flux.just("Apple", "Banana", "Cat"),  // Name
                Flux.just(11, 22, 33)   // Age
        ).doOnNext(t -> System.out.printf("User[id=%d, name=%s, age=%s]\n", t.getT1(), t.getT2(), t.getT3()))
                .subscribe();
    }
}
